package com.application.model;

import com.application.common.OrderStatus;
import com.application.condition.OrderCondition;
import com.jfinal.kit.StrKit;
import com.jfinal.log.Log;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.platform.annotation.Table;
import com.platform.mvc.base.BaseModel;
import com.platform.mvc.user.User;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.List;
import java.util.Map;

/**
 */
@SuppressWarnings("unused")
@Table(tableName = Order.table_name, pkName = "id")
public class Order extends BaseModel<Order> {

    private static final long serialVersionUID = 6761767368352810428L;

    private static final Log log = Log.getLog(Order.class);

    public static final Order dao = new Order().dao();

    /**
     * 表名称
     */
    public static final String table_name = "t_order";

    public static String sqlId_splitPageSelect = "com.application.order.splitPageSelect";
    public static String sqlId_splitPageFrom = "com.application.order.splitPageFrom";

    /*   订单类型
        */
    public final static int TYPE_VIP_CHARGE = 1;//会员充值
    public final static int TYPE_PLAY_COUPON = 2;//购买播放券
    public final static int TYPE_COURSE = 3;//购买课程


    public static final String PAY_YE = "ye";
    public static final String PAY_WX = "wx";
    public static final String PAY_XCX = "xcx";
    public static final String PAY_ZFB = "zfb";

    private Integer id;
    private Integer order_userid;
    private String order_username;
    private Integer order_type;
    private String order_no;
    private Integer order_status;
    private String order_memo;
    private BigDecimal order_price;
    private Integer order_date;
    private Timestamp order_print_time;
    private Integer use_point;
    private String pay_type;
    private BigDecimal pay_amount;
    private Timestamp pay_time;
    private BigDecimal cost_money;
    private Integer cost_coupon_id;
    private Integer cost_coupon_value;
    private Timestamp create_time;
    private Timestamp update_time;
    private Timestamp delete_time;
    private Integer delete_userid;
    private BigDecimal total_amount;
    private Integer module_id;

    public Integer getModule_id() {
        return get("module_id");
    }
    public void setModule_id(Integer module_id) {
        set("module_id", module_id);
    }

    public void setId(Integer id){
        set("id", id);
    }
    public Integer getId() {
        return get("id");
    }
    public void setOrder_userid(Integer order_userid){
        set("order_userid", order_userid);
    }
    public Integer getOrder_userid() {
        return get("order_userid");
    }
    public void setOrder_username(String order_username){
        set("order_username", order_username);
    }
    public String getOrder_username() {
        return get("order_username");
    }
    public void setOrder_type(Integer order_type){
        set("order_type", order_type);
    }
    public Integer getOrder_type() {
        return get("order_type");
    }
    public void setOrder_no(String order_no){
        set("order_no", order_no);
    }
    public String getOrder_no() {
        return get("order_no");
    }
    public void setOrder_status(Integer order_status){
        set("order_status", order_status);
    }
    public Integer getOrder_status() {
        return get("order_status");
    }
    public void setOrder_memo(String order_memo){
        set("order_memo", order_memo);
    }
    public String getOrder_memo() {
        return get("order_memo");
    }
    public void setOrder_price(BigDecimal order_price){
        set("order_price", order_price);
    }
    public BigDecimal getOrder_price() {
        return get("order_price");
    }
    public void setOrder_date(Integer order_date){
        set("order_date", order_date);
    }
    public Integer getOrder_date() {
        return get("order_date");
    }
    public void setOrder_print_time(Timestamp order_print_time){
        set("order_print_time", order_print_time);
    }
    public Timestamp getOrder_print_time() {
        return get("order_print_time");
    }
    public void setUse_point(Integer use_point){
        set("use_point", use_point);
    }
    public Integer getUse_point() {
        return get("use_point");
    }
    public void setPay_type(String pay_type){
        set("pay_type", pay_type);
    }
    public String getPay_type() {
        return get("pay_type");
    }
    public void setPay_amount(BigDecimal pay_amount){
        set("pay_amount", pay_amount);
    }
    public BigDecimal getPay_amount() {
        return get("pay_amount");
    }
    public void setPay_time(Timestamp pay_time){
        set("pay_time", pay_time);
    }
    public Timestamp getPay_time() {
        return get("pay_time");
    }
    public void setCost_money(BigDecimal cost_money){
        set("cost_money", cost_money);
    }
    public BigDecimal getCost_money() {
        return get("cost_money");
    }
    public void setCost_coupon_id(Integer cost_coupon_id){
        set("cost_coupon_id", cost_coupon_id);
    }
    public Integer getCost_coupon_id() {
        return get("cost_coupon_id");
    }
    public void setCost_coupon_value(Integer cost_coupon_value){
        set("cost_coupon_value", cost_coupon_value);
    }
    public Integer getCost_coupon_value() {
        return get("cost_coupon_value");
    }
    public void setCreate_time(Timestamp create_time){
        set("create_time", create_time);
    }
    public Timestamp getCreate_time() {
        return get("create_time");
    }
    public void setUpdate_time(Timestamp update_time){
        set("update_time", update_time);
    }
    public Timestamp getUpdate_time() {
        return get("update_time");
    }
    public void setDelete_time(Timestamp delete_time){
        set("delete_time", delete_time);
    }
    public Timestamp getDelete_time() {
        return get("delete_time");
    }
    public void setDelete_userid(Integer delete_userid){
        set("delete_userid", delete_userid);
    }
    public Integer getDelete_userid() {
        return get("delete_userid");
    }

    public BigDecimal getTotal_amount() {
        return get("total_amount");
    }

    public Page<Order> findList(int num, int size, List<Integer> statusArr, OrderCondition condition) {
        String sel = "select a.* ";
        String from = "from t_order a where a.delete_time is null " +
                getQueryString(statusArr, condition) + " order by a.id desc";

        return paginate(num, size, sel, from);
    }

    private String getQueryString(List<Integer> statusArr, OrderCondition q) {
        StringBuffer sb = new StringBuffer(1000);
        sb.append(getStatusSqlString(statusArr));
        sb.append(q.getQuerySql());
        return sb.toString();
    }

    public static String getStatusSqlString(List<Integer> statusArr) {
        StringBuffer sb = new StringBuffer();
        if (statusArr.size() > 0) {
            sb.append(" and (");
            for (int i = 0; i < statusArr.size(); i++) {
                sb.append("  order_status = " + statusArr.get(i));
                if (i != statusArr.size() - 1) {
                    sb.append(" or ");
                }
            }
            sb.append(" ) ");
        }
        return sb.toString();
    }

    public Order findDetail(Integer id) {
        Order order = findById(id);
        //查询订单项目
        //查询下单人信息
        User createUser = User.dao.findById(order.getInt("order_userid"));

        if(createUser == null) {
            order.put("mobile", "未知");
            order.put("create_username", "未知");
        } else {
            order.put("mobile", createUser.get("mobile"));
            order.put("create_username", createUser.getName());
        }

        //修改小程序支付显示
        String type = order.getPay_type();
        if(StrKit.notBlank(type) && type.equalsIgnoreCase(Order.PAY_XCX)) {
            order.setPay_type(Order.PAY_WX);
        }

        return order;
    }

    public Order findByNumber(String out_trade_no) {
        return findFirst("select * from " + table_name + " where order_no = ?", out_trade_no);
    }

    public long queryByStatus(int userid, int status) {
        String sql = "select count(*) from " + table_name +
                " where order_userid = ? and order_status = ? and delete_time is null ";
        return Db.queryLong(sql, userid, status);
    }


    /*
    取消订单，恢复库存、积分、优惠券等信息（对应下单操作）
     */
    public boolean cancel(Integer id, String desc, int userid, int orderStatus) {
        boolean f = Db.tx(() -> {
            Order order = findById(id);
            boolean t = order.set("order_status", orderStatus).update();
            OrderFlow.dao.create(id, orderStatus, userid, desc);
            afterCancelOrder(order.getCost_coupon_id(), order.getUse_point(), userid, id);
            return t;
        });
        return f;
    }

    private void afterCancelOrder(Integer userCouponId, int userPoint, int userid, int orderId) {
        //记录积分消费
        if (userPoint > 0) {
            UserPoint.dao.restore(userid, userPoint, orderId);
        }
    }

    /*
    只有已付款并且发货前的商品订单可以申请退款。
提交申请退款后，状态变为退款中，有后台处理统一退款后才可退款成功
     */
    public boolean applyRefund(Integer id, String desc, int userid) {
        Order order = findById(id);
        if (order != null) {
            if (order.getOrder_status() == OrderStatus.PAY_OVER) {
                order.setOrder_status(OrderStatus.REFUND_WAIT);
                OrderFlow.dao.create(order.getId(), OrderStatus.REFUND_WAIT, userid, desc);
                OrderRefund.dao.create(order.getId(), userid, order.getPay_amount().toString(), desc);
                return order.update();
            }
        }
        return false;
    }

    /**
     * 订单ID
     * 评价内容
     * 图片：0~9张
     * 是否匿名
     */
    public boolean comment(int userid, Integer id, Map<String, String> map) {
        int star = Integer.parseInt(map.get("star"));
        return false;
    }


    public String getOrderNewNo(Order order) {
        String no = order.getOrder_no();
        int end = no.length() > 18 ? Integer.parseInt(no.substring(18)) + 1 : 1;
        return no.substring(0, 18) + end;
    }

    public Order findLastOrder(int userId) {
        return findFirst("select * from "+ table_name + " where order_userid = ? order by id ", userId);
    }

    public BigDecimal findTotalAmountByDate(String mStart, String mEnd) {
        String s = "SELECT sum(COALESCE(pay_amount, 0)) as total_amount\n" +
                "       from t_order where delete_time is null and pay_time between ? and ? and order_status = ?";
        return Db.queryBigDecimal(s, mStart, mEnd, OrderStatus.PAY_OVER);
    }

    public BigDecimal findTotalRebateByDate(String mStart, String mEnd) {
        String s = "SELECT sum(cast(money_1 as decimal(10,2))) + sum(cast(money_2 as decimal(10,2))) as rebate_amount\n" +
                "   from t_rebate_history a\n" +
                "   left join t_order b on a.order_no = b.order_no where delete_time is null" +
                "   and pay_time between ? and ?";
        return Db.queryBigDecimal(s, mStart, mEnd);
    }
}
